package com.zxw.common.web.util;

import cn.hutool.json.JSONObject;
import com.zxw.common.core.base.constant.SysConstants;

import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author zhangxuewei
 */
public class InitPropertyValueUtils {


    /**
     * 反射获取获取会话中的数据，初始化更新元信息
     *
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T initSelectValue(T t) {
        Map<String, String> initPropertyMap = new LinkedHashMap<String, String>() {{
            putAll(SysConstants.INIT_SELECT_PROPERTY_MAP);
        }};
        JSONObject jsonObject = JwtUtils.getJwtPayload();
        setInitValue(initPropertyMap, jsonObject, t);
        return t;
    }

    /**
     * 反射获取获取会话中的数据，初始化更新元信息
     *
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T initInsertValue(T t) {
        Map<String, String> initPropertyMap = new LinkedHashMap<String, String>() {{
            putAll(SysConstants.INIT_INSERT_PROPERTY_MAP);
        }};
        JSONObject jsonObject = JwtUtils.getJwtPayload();
        setInitValue(initPropertyMap, jsonObject, t);
        return t;
    }

    /**
     * 反射获取获取会话中的数据，初始化更新元信息
     *
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T initUpdateValue(T t) {
        Map<String, String> initPropertyMap = new LinkedHashMap<String, String>() {{
            putAll(SysConstants.INIT_UPDATE_PROPERTY_MAP);
        }};
        JSONObject jsonObject = JwtUtils.getJwtPayload();
        setInitValue(initPropertyMap, jsonObject, t);
        return t;
    }

    /**
     * 反射获取属性信息，给赋值方法 传递
     *
     * @param initPropertyMap
     * @param jsonObject
     * @param t
     * @param <T>
     * @return
     */
    private static <T> T setInitValue(Map<String, String> initPropertyMap, JSONObject jsonObject, T t) {
        setPropertyValue(initPropertyMap, jsonObject, t.getClass().getFields(), t);
        Class<?> superclass = t.getClass();
        while (superclass != null) {
            if (superclass.getName().equals("java.lang.Object")) {
                break;
            }
            setPropertyValue(initPropertyMap, jsonObject, superclass.getDeclaredFields(), t);
            superclass = superclass.getSuperclass();
        }
        return t;
    }

    /**
     * 根据initPropertyMap初始化value
     *
     * @param initPropertyMap
     * @param jsonObject
     * @param fields
     * @param t
     * @param <T>
     * @return
     */
    private static <T> T setPropertyValue(Map<String, String> initPropertyMap, JSONObject jsonObject, Field[] fields, T t) {
        for (Field field : fields) {
            if (!initPropertyMap.containsKey(field.getName()))
                continue;
            String property = initPropertyMap.get(field.getName());
            field.setAccessible(true);
            if (initPropertyMap.size() == 0)
                break;
            try {
                if (field.getType().getTypeName().equals("java.time.LocalDateTime")) {
                    if (null == field.get(t) && field.getName().equals(SysConstants.CREATE_TIME_PROPERTY))
                        field.set(t, LocalDateTime.now());
                    else if (field.getName().equals(SysConstants.LAST_UPDATE_TIME_PROPERTY))
                        field.set(t, LocalDateTime.now());
                } else if (field.getType().getTypeName().equals("java.lang.Long"))
                    field.set(t, jsonObject.getLong(property));
                else
                    field.set(t, jsonObject.get(property));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            initPropertyMap.remove(field.getName());
        }
        return t;
    }


}
